#include "headerfunciones.h"

long int NO_ME_MIRES = 0;//variable asignada para contar el numero de instrucciones de un algoritmo

/////////////////////////////////////////////////
//                                             //
//	Funcion fibonacci (finalizada)			   //
//	Funcion sumatoria (finalizada)			   //
//	Funcion productiMatriz (finalizada)		   //
//  Contar tiempos de ejecucion (incompleta?)  //
// 	Escritura y lectura (incompleta)		   //
//											   //	
/////////////////////////////////////////////////


long int fibonacci(int num)
{
	NO_ME_MIRES++;
	if(num == 1 || num == 0)
	{
		
		return 1;
	}
	else
		return fibonacci(num-1) + fibonacci(num-2);	
}

void sumatoria(float arreglo[], int n, float *suma, long int *contadorInstrucciones)
{
	int i;
	*contadorInstrucciones = 0;
	for(i = 0; i < n ; i++)//se recorre el arreglo y se suman los terminos orden "n"
	{
		*suma += arreglo[i];
		*contadorInstrucciones += 1;
	}
}
float *crearVector(FILE *archivo, float numero)
{
	int contador;
	float *arreglo = malloc(numero*sizeof(float));//se asigna el espacio al arreglo
	for(contador = 0; contador < numero; contador++)
	{
		fscanf(archivo,"%f", &arreglo[contador]);//se lee el archivo y se le asigna los valores al arreglo
	}
	return arreglo;
}	

float *crearMatriz(FILE *archivo, int fila, int columna)
{
	float *Matriz = malloc((columna*fila)*sizeof(int));//se asigna el espacio para la "matriz" 
	int cont;
	if(Matriz == NULL)//se ve si es posible asignar el espacio sino se llena la matriz
		printf("es NULL");
	else
	{	
		for(cont = 0; cont != (fila*columna); cont++)
			fscanf(archivo, "%f", &Matriz[cont]);
	}	
	return Matriz;
}

void saltoEnLinea(FILE *archivo)
{
	char salto;
	while(salto!= '\n')//lee el archivo hasta encontrarse con un salto en line
		fscanf(archivo,"%c", &salto);
}

void productoMatriz(float matriz[] , float vector[], int fila, int columna, float *resultado, long int *contadorInstrucciones)
{
	float suma;                   //
	int i, j, nfm;                //   se crean las variables i y j para hacer las iteraciones,          
	nfm =0;                       //   ademas como este arreglo se trata como matriz se crea la variable nfm          
	suma = 0;                     //   la que se suma después de completar una cantidad de operaciones igual al numero           
	*contadorInstrucciones= 0;    //   osea si el numero de columnas es 4 ira:           
	for(i = 0; i != fila; i++)    //   con nfm = 0; 
	{                             //    1 + nfm = 1, 2 + nfm = 2, 3 + nfm = 3, 4 + nfm = 4
		for(j = 0; j != columna; j++)// con nfm = 4;
		{                            // 1+ nfm = 5, 2+nfm = 6, 3+nfm = 7, 4+nfm = 8 y asi...
			suma +=vector[j]*matriz[j+nfm];
			(*contadorInstrucciones)++; 
		}
		resultado[i] = suma;
		nfm += columna;
		suma = 0;
	}
}
float *resultadoProducto(int fila)
{
	float *resultado = calloc(fila,sizeof(float));//se crea el espacio para el resultado de producto matrizx
	return resultado;
}

void lecturaEscritura(char nombre[20])
{
	//se crean las variables que seran utilizadas
	float lectura, suma; //lectura: se almacena el resultado de la lectura del archivo,  suma: el resuñtado de "sumatoria"
	int contador, aux, numero;//contador: el numero de veses a ejecutaran los valores de prueba, aux: variable auxiliar para actualizar el contador, numero: se usa para guardar el numero que se quiere obtener en "fibonacci"
	long int contadorInstrucciones;// cuenta las instrucciones en las funciones que se puede usar,
	int fila, columna, i;//se utilizan en la lectura y ejecucion para "productoMatriz"
	//se abren y crean los archivos que se ocuparan
	FILE *archivo = fopen(nombre, "r");
	FILE *matriz = fopen("matriz.txt", "w+");
	FILE *outputArch = fopen("output.txt", "w+");
	//comienza la lectura y escritura
	fscanf(archivo,"%i", &contador);
	aux = contador;
	//lectura y escritura para sumatoria
	for(;contador!=0; contador--)
	{
		fscanf(archivo, "%f", &lectura);
		float *punteroArreglo = crearVector(archivo, lectura+1);//se ejecuta la funcion crearVector y se le asigna un puntero
		suma = 0;
		sumatoria(punteroArreglo, lectura+1, &suma, &contadorInstrucciones);//se ejecuta la funcion sumatoria
		fprintf(outputArch, "instrucciones ejecutadas: %li suma: %f,", contadorInstrucciones, suma);//se escribe el archivo output.txt
		saltoEnLinea(archivo);
		free(punteroArreglo);//se libera el espacio ocupado
	}
	fprintf(outputArch, "\n");
	//lectura y escritura para producto matriz
	for(contador = aux;contador !=0; contador--)
	{
		//se asignan valores a las filas y columnas
		fscanf(archivo,"%i %i",&fila,&columna);
		float *resultado = resultadoProducto(fila);
		float *punteroMatriz = crearMatriz(archivo, fila, columna);
		float *punteroVector = crearVector(archivo, columna);
		productoMatriz(punteroMatriz, punteroVector, fila, columna, resultado, &contadorInstrucciones);	//se ejecuta "productoMatriz"
		
		for(i=0; i < fila; i++)
			fprintf(matriz,"%d ", (int)resultado[i]);
		
		fprintf(matriz, " \n");
		fprintf(outputArch, "Instrucciones ejecutadas: %li ,", contadorInstrucciones);
		//se libera espacio en la memoria
		free(resultado);
		free(punteroMatriz);
		free(punteroVector);
	}
	fprintf(outputArch, " \n");
	for(contador = aux;contador != 0; contador--)
	{
		fscanf(archivo, "%d", &numero);
		fprintf(outputArch, "Numero: %li Instrucciones ejecutas: %li ,", fibonacci(numero), NO_ME_MIRES);//se ejecuta "fibonacci" y escriben los resultados
		NO_ME_MIRES = 0;
	}
	//se cierran los archivo utilizados
	fclose(archivo);
	fclose(matriz);
	fclose(outputArch);
}
